﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using WindowsAPI.Service;
using WindowsAPI.Windows;

// ReSharper disable FieldCanBeMadeReadOnly.Global
namespace WindowsAPI
{
    [SuppressUnmanagedCodeSecurity, Dll(FileName)]
    public static class Shell32
    {
        /* ------------------------------------------------------------------------------------------ */

        public const string FileName = "shell32.dll";

        /* ------------------------------------------------------------------------------------------ */

        [DllImport(FileName, CharSet = CharSet.Auto)]
        public static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);

        public static bool ShellExecute(string File, string Directory = null, bool ShowCmd = false)
        {
            return ShellExecute(IntPtr.Zero, "OPEN", File, null, Directory, ShowCmd) != IntPtr.Zero;
        }

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr ShellExecute(IntPtr hWnd, string Operation, string File, string lParams,
            string Directoty, bool ShowCmd);

        /// <summary>Tests whether the current user is a member of the Administrator's group.</summary>
        /// <returns>Returns TRUE if the user is a member of the Administrator's group; otherwise, FALSE.</returns>
        /// <remarks>
        /// This function is a wrapper for CheckTokenMembership. 
        /// It is recommended to call that function directly to determine Administrator group status rather than calling IsUserAnAdmin.
        ///' </remarks>
        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool IsUserAnAdmin();

        [DllImport(FileName, SetLastError = true)]
        public static extern uint DragQueryFile(IntPtr hDrop, uint iFile, [Out] StringBuilder lpszFile, int cch);

        /// <summary>
        /// Функция извлекает дескриптор значка из указанного исполняемого файла, динамически подключаемой библиотеки (DLL) или файла значка.
        /// System.Drawing.Icon.ExtractAssociatedIcon(fileName);
        /// </summary>
        /// <param name="Handle">Дескриптор экземпляра приложения, вызывающего функцию. По умолчанию = IntPtr.Zero</param>
        /// <param name="FileName">Имя файла</param>
        /// <param name="IconIndex">Индекс значка</param>
        /// <returns>
        /// Возвращаемое значение - дескриптор значка. Если определенный файл не был исполняемым файлом, 
        /// динамически подключаемой библиотекой (DLL) или файлом значка, возвращается 1. 
        /// Если никакие значки не были найдены в файле, возвращаемое значение - NULL.
        /// Если IconIndex = -1, функция возвращает общее количество значков в указанном файле.
        /// </returns>
        /// <remarks>Необходимо уничтожить все значки, при помощи вызова функции DestroyIcon</remarks>
        [DllImport(FileName, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr ExtractIcon(IntPtr Handle, string FileName, int IconIndex);

        /// <summary>
        /// Извлечение указателя на значёк PE файла
        /// System.Drawing.Icon.ExtractAssociatedIcon(fileName);
        /// </summary>
        /// <param name="FileName">Имя файла</param>
        /// <param name="IconIndex">
        /// Определяет отсчитываемый от нуля индекс первого извлекаемого значка. 
        /// Например, если значение = 0, то функция извлекает первый значок в указанном файле.
        /// </param>
        /// <param name="IconLarge">
        /// Указатель на массив дескрипторов значка, который получает дескрипторы больших значков, извлеченных из файла. 
        /// Если этот параметр - NULL, никакие большие значки не извлекаются из файла.
        /// </param>
        /// <param name="IconSmall">
        /// Указатель на массив дескрипторов значка, который получает дескрипторы маленьких значков, извлеченных из файла. 
        /// Если этот параметр - NULL, никакие маленькие значки не извлекаются из файла.
        /// </param>
        /// <param name="Icons">Определяет число значков, извлекаемых из файла.</param>
        /// <returns>
        /// Если IconIndex = -1, а параметры IconLarge = IconSmall = NULL, то  функцией возвращает общее количество значков в указанном файле.
        /// Если файл - это исполняемый файл или динамически подключаемая библиотека (DLL), то возвращаемое значение - число ресурсов RT_GROUP_ICON. 
        /// Если файл - .ICO файл, возвращаемое значение равно 1
        /// </returns>
        /// <remarks>Необходимо уничтожить все значки, при помощи вызова функции DestroyIcon</remarks>
        [DllImport(FileName, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern uint ExtractIconEx(string FileName, int IconIndex, IntPtr[] IconLarge,
            IntPtr[] IconSmall, uint Icons);

        //[DllImport(FileName, CharSet = CharSet.Auto, SetLastError = true)]
        //public static extern IntPtr ShellExecute(
        //    IntPtr hWnd,
        //    string lpOperation,
        //    string lpFile,
        //    string lpParameters,
        //    string lpDirectory,
        //    ShowCommands nShowCmd);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="hWnd">Handle to a parent window</param>
        /// <param name="lpOperation">
        /// Pointer to a null-terminated string, referred to in this case as a verb, that specifies the action to be performed
        /// </param>
        /// <param name="lpFile">
        /// Pointer to a null-terminated string that specifies the file or object on which to execute the specified verb 
        /// </param>
        /// <param name="lpParameters">
        /// If the lpFile parameter specifies an executable file, lpParameters is a pointer to a null-terminated string 
        /// that specifies the parameters to be passed to the application 
        /// </param>
        /// <param name="lpDirectory">Pointer to a null-terminated string that specifies the default directory</param>
        /// <param name="nShowCmd"></param>
        /// <returns></returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr ShellExecute(
                    IntPtr hWnd,
                    [MarshalAs(UnmanagedType.LPTStr)] string lpOperation,
                    [MarshalAs(UnmanagedType.LPTStr)] string lpFile,
                    [MarshalAs(UnmanagedType.LPTStr)] String lpParameters,
                    [MarshalAs(UnmanagedType.LPTStr)] string lpDirectory,
                    ShowCommands nShowCmd);

        /// <summary>
        /// Retrieves information about an object in the file system, such as a file, a folder, a directory, or a drive root.
        /// (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shgetfileinfo.asp)
        /// </summary>
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr SHGetFileInfo(
                    string pszPath,				//path
                    eFileAttributes dwFileAttributes,		//attributes
                    ref SHFILEINFO psfi,		//struct pointer
                    uint cbSizeFileInfo,		//size
                    SHGFI uFlags);

        //flags

        // Flags that specify how an application is to be 
        // displayed when it is opened.

        /// <summary>
        /// Функция позволяет производить копирование, перемещение, переименование и удаление 
        /// (в том числе и в Recycle Bin) объектов файловой системы
        /// </summary>
        /// <param name="lpFileOp">структуру типа TSHFileOpStruct, в которой и передаются все необходимые данные</param>
        /// <returns>Возвращает false, если операция выполнена успешно, и ненулевое значение в противном случае.</returns>
        /// <remarks>
        /// Если pFrom или pTo не указаны, берутся файлы из текущей директории. 
        /// Текущую директорию можно установить с помощью функции SetCurrentDirectory и получить функцией GetCurrentDirectory
        /// </remarks>
        [DllImport(FileName, SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool SHFileOperation([In] ref SHFILEOPSTRUCT lpFileOp);

        [DllImport(FileName, SetLastError = true, EntryPoint = "#2", CharSet = CharSet.Auto)]
        public static extern uint SHChangeNotifyRegister(
                    IntPtr hWnd,
                    SHCNF fSources,
                    SHCNE fEvents,
                    uint wMsg,
                    int cEntries,
                    ref SHChangeNotifyEntry pFsne);

        //[DllImport(FileName, SetLastError = true, EntryPoint = "#4", CharSet = CharSet.Auto)]
        //[return: MarshalAs(UnmanagedType.Bool)]
        //public static extern Boolean SHChangeNotifyUnregister(
        //            ulong hNotify);

        [DllImport(FileName, EntryPoint = "#2", CharSet = CharSet.Auto)]
        public static extern uint SHChangeNotifyRegister(
                    IntPtr hWnd,
                    SHCNF fSources,
                    SHCNE fEvents,
                    WM wMsg,
                    int cEntries,
                    ref SHChangeNotifyEntry pFsne);

        [DllImport(FileName, EntryPoint = "#4", CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern Boolean SHChangeNotifyUnregister(ulong hNotify);

        [DllImport(FileName, CharSet = CharSet.Auto)]
        public static extern int SHGetFileInfoA(
                    uint Pidl,
                    uint FileAttributes,
                    out SHFILEINFO Fi,
                    uint FileInfo,
                    SHGFI Flags);

        [DllImport(FileName, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern Boolean SHGetPathFromIDList(
                    [In] IntPtr pidl,
                    [In, Out, MarshalAs(UnmanagedType.LPTStr)] String pszPath);

        [DllImport(FileName, CharSet = CharSet.Auto)]
        public static extern uint SHGetSpecialFolderLocation(
                    IntPtr hWnd,
                    CSIDL nFolder,
                    out IntPtr Pidl);

        [DllImport(FileName)]
        public static extern void SHChangeNotify(int wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);

        /// <summary>
        /// Adds a document to the Shell's list of recently used documents or clears all documents from the list
        /// </summary>
        /// <param name="uFlags"></param>
        /// <param name="path"></param>
        [DllImport(FileName, CharSet = CharSet.Ansi)]
        public static extern void SHAddToRecentDocs(
                    ShellAddToRecentDocsFlags uFlags = ShellAddToRecentDocsFlags.Pidl,
                    [MarshalAs(UnmanagedType.LPWStr)] string path = null);

        public static void AddToRecentDocs(string path) { SHAddToRecentDocs(ShellAddToRecentDocsFlags.Path, path); }

        public static void AddToRecentDocs(FileInfo path) { SHAddToRecentDocs(ShellAddToRecentDocsFlags.Path, path.FullName); }

        public static void ClearRecentDocs() { SHAddToRecentDocs(); }

        [DllImport(FileName)]
        public static extern bool SHInvokePrinterCommand(
                IntPtr hwnd,
                PrinterActions uAction,
                [In]string lpBuf1,
                [In, Optional]string lpBuf2,
                bool fModal);

        /// <summary>Sends an appbar message to the system</summary>
        /// <param name="dwMessage">Appbar message value to send</param>
        /// <param name="pData"></param>
        /// <returns></returns>
        [DllImport(FileName)]
        public static extern uint SHAppBarMessage(
                    AppBarMessages dwMessage,
                    ref APPBARDATA pData);

        /* ------------------------------------------------------------------------------------------ */
    }

    [StructLayout(LayoutKind.Sequential)]
    [Serializable]
    public struct SHELLEXECUTEINFO
    {
        public static SHELLEXECUTEINFO Default { get { return new SHELLEXECUTEINFO { cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO)) }; } }

        public int cbSize;
        public int fMask;
        public IntPtr hwnd;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string lpVerb;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string lpFile;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string lpParameters;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string lpDirectory;
        public int nShow;
        public IntPtr hInstApp;
        public int lpIDList;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string lpClass;
        public IntPtr hkeyClass;
        public int dwHotKey;
        public IntPtr hIcon;
        public IntPtr hProcess;
    }

    /// <summary>Appbar message value to send</summary>
    [Serializable]
    public enum AppBarMessages
    {
        /// <summary>
        /// Registers a new appbar and specifies the message identifier that 
        /// the system should use to send notification messages to the appbar.
        /// </summary>
        New = 0x00000000,
        /// <summary>Unregisters an appbar, removing the bar from the system's internal list.</summary>
        Remove = 0x00000001,
        /// <summary>Requests a size and screen position for an appbar</summary>
        QueryPos = 0x00000002,
        /// <summary>Sets the size and screen position of an appbar</summary>
        SetPos = 0x00000003,
        /// <summary>Retrieves the autohide and always-on-top states of the Microsoft® Windows® taskbar</summary>
        GetState = 0x00000004,
        /// <summary>Retrieves the bounding rectangle of the Windows taskbar</summary>
        GetTaskBarPos = 0x00000005,
        /// <summary>Notifies the system that an appbar has been activated</summary>
        Activate = 0x00000006,
        /// <summary>Retrieves the handle to the autohide appbar associated with a particular edge of the screen</summary>
        GetAutoHideBar = 0x00000007,
        /// <summary>Registers or unregisters an autohide appbar for an edge of the screen</summary>
        SetAutoHideBar = 0x00000008,
        /// <summary>Notifies the system when an appbar's position has changed</summary>
        WindowPosChanged = 0x00000009,
        /// <summary>Sets the state of the appbar's autohide and always-on-top attributes</summary>
        SetState = 0x0000000a
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct APPBARDATA
    {
        public uint cbSize;
        public IntPtr hWnd;
        public uint uCallbackMessage;
        public uint uEdge;
        public RECT rc;
        public int lParam;
    }

    public enum PrinterActions
    {
        Open,
        Properties,
        NetInstall,
        NetInstallLink,
        TestPage,
        OpenNetPrn,
        DocumentDefaults,
        ServerProperties
    }

    public enum ShellAddToRecentDocsFlags
    {
        /// <summary>The pv parameter points to a null-terminated string with the path and file name of the object</summary>
        Pidl = 0x001,
        /// <summary>
        /// The pv parameter points to a pointer to an item identifier list (PIDL) that identifies the document's file object. 
        /// PIDLs that identify nonfile objects are not allowed
        /// </summary>
        Path = 0x002,
        /// <summary>
        /// The pv parameter points to a pointer to an item identifier list (PIDL) that identifies the document's file object. 
        /// PIDLs that identify nonfile objects are not allowed
        /// </summary>
        PathA = Path,
        /// <summary>Same as SHARD_PATHA but unicode string</summary>
        PAthW = 0x003
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SHNOTIFYSTRUCT
    {
        public IntPtr dwItem1;
        public IntPtr dwItem2;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct SHChangeNotifyEntry
    {
        public IntPtr pIdl;
        [MarshalAs(UnmanagedType.Bool)]
        public Boolean Recursively;
    }

    [Flags]
    public enum SHCNE : uint
    {
        SHCNE_RENAMEITEM = 0x00000001,
        SHCNE_CREATE = 0x00000002,
        SHCNE_DELETE = 0x00000004,
        SHCNE_MKDIR = 0x00000008,
        SHCNE_RMDIR = 0x00000010,
        SHCNE_MEDIAINSERTED = 0x00000020,
        SHCNE_MEDIAREMOVED = 0x00000040,
        SHCNE_DRIVEREMOVED = 0x00000080,
        SHCNE_DRIVEADD = 0x00000100,
        SHCNE_NETSHARE = 0x00000200,
        SHCNE_NETUNSHARE = 0x00000400,
        SHCNE_ATTRIBUTES = 0x00000800,
        SHCNE_UPDATEDIR = 0x00001000,
        SHCNE_UPDATEITEM = 0x00002000,
        SHCNE_SERVERDISCONNECT = 0x00004000,
        SHCNE_UPDATEIMAGE = 0x00008000,
        SHCNE_DRIVEADDGUI = 0x00010000,
        SHCNE_RENAMEFOLDER = 0x00020000,
        SHCNE_FREESPACE = 0x00040000,
        SHCNE_EXTENDED_EVENT = 0x04000000,
        SHCNE_ASSOCCHANGED = 0x08000000,
        SHCNE_DISKEVENTS = 0x0002381F,
        SHCNE_GLOBALEVENTS = 0x0C0581E0,
        SHCNE_ALLEVENTS = 0x7FFFFFFF,
        SHCNE_INTERRUPT = 0x80000000,
    }

    [Flags]
    public enum SHCNRF
    {
        InterruptLevel = 0x1,
        ShellLevel = 0x2,
        RecursiveInterrupt = 0x1000,
        NewDelivery = 0x8000,
    }

    [Flags]
    public enum SHCNF
    {
        SHCNF_IDLIST = 0x0000,
        SHCNF_PATHA = 0x0001,
        SHCNF_PRINTERA = 0x0002,
        SHCNF_DWORD = 0x0003,
        SHCNF_PATHW = 0x0005,
        SHCNF_PRINTERW = 0x0006,
        SHCNF_TYPE = 0x00FF,
        SHCNF_FLUSH = 0x1000,
        SHCNF_FLUSHNOWAIT = 0x2000
    }



    /// <summary>Структура, описывающая файловую операцию</summary>
    /// <remarks>
    /// Если pFrom или pTo не указаны, берутся файлы из текущей директории. 
    /// Текущую директорию можно установить с помощью функции SetCurrentDirectory и получить функцией GetCurrentDirectory
    /// </remarks>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SHFILEOPSTRUCT
    {
        /// <summary>Хэндл окна, на которое будут выводиться диалоговые окна о ходе операции</summary>
        public IntPtr hwnd;
        /// <summary>Требуемая операция</summary>
        public FileFuncFlags wFunc;
        /// <summary>
        /// Указатель на буфер, содержащий пути к одному или нескольким файлам. 
        /// Если файлов несколько, между путями ставится нулевой байт. Список должен заканчиваться двумя нулевыми байтами
        /// </summary>
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pFrom;
        /// <summary>
        /// Аналогично pFrom, но содержит путь к директории - адресату, в которую производится копирование или перемещение файлов. 
        /// Также может содержать несколько путей. При этом нужно установить флаг FOF_MULTIDESTFILES
        /// </summary>
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pTo;
        /// <summary>Управляющие флаги</summary>
        public FILEOP_FLAGS fFlags;
        /// <summary>Принимает значение TRUE если пользователь прервал любую файловую операцию до ее завершения и FALSE в ином случае</summary>
        [MarshalAs(UnmanagedType.Bool)]
        public bool fAnyOperationsAborted;
        /// <summary>
        /// Дескриптор объекта отображения имени файла, который содержит массив структур SHNAMEMAPPING. 
        /// Каждая структура содержит старые и новые имена пути для каждого файла, который перемещался, скопирован, 
        /// или переименован. Этот элемент используется только, если установлен флаг FOF_WANTMAPPINGHANDLE
        /// </summary>
        public IntPtr hNameMappings;
        /// <summary>
        /// Указатель на строку, используемую как заголовок для диалогового окна прогресса. 
        /// Этот элемент используется только, если установлен флаг FOF_SIMPLEPROGRESS
        /// </summary>
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpszProgressTitle;
    }

    /// <summary>Требуемая операция</summary>
    [Flags]
    public enum FileFuncFlags : uint
    {
        /// <sumary>Перемещает файлы, указанные в pFrom в папку, указанную в pTo</sumary>
        FO_MOVE = 0x1,
        /// <summary>Копирует файлы, указанные в pFrom в папку, указанную в pTo</summary>
        FO_COPY = 0x2,
        /// <summary>Удаляет файлы, указанные pFrom (pTo игнорируется)</summary>
        FO_DELETE = 0x3,
        /// <summary>Переименовывает файлы, указанные в pFrom</summary>
        FO_RENAME = 0x4
    }

    /// <summary>Управляющие флаги</summary>
    [Flags]
    public enum FILEOP_FLAGS : ushort
    {
        /// <summary>Указывает, что для каждого исходного файла в поле pFrom указана своя директория - адресат</summary>
        FOF_MULTIDESTFILES = 0x1,
        /// <summary>Не реализовано</summary>
        FOF_CONFIRMMOUSE = 0x2,
        /// <summary>Не показывать диалог с индикатором прогресса</summary>
        FOF_SILENT = 0x4,
        /// <summary>В случае, если уже существует файл с данным именем, создается файл с именем "Copy #N of..."</summary>
        FOF_RENAMEONCOLLISION = 0x8,
        /// <summary>Отвечает "yes to all" на все запросы в ходе опеации</summary>
        FOF_NOCONFIRMATION = 0x10,
        /// <summary>Вносит hNameMappings элемент. Дескриптор должен быть освобожден функцией SHFreeNameMappings</summary>
        FOF_WANTMAPPINGHANDLE = 0x20,
        /// <summary>Если возможно, сохраняет информацию для возможности UnDo</summary>
        FOF_ALLOWUNDO = 0x40,
        /// <summary>Если в поле pFrom установлено *.*, то операция будет производиться только с файлами</summary>
        FOF_FILESONLY = 0x80,
        /// <summary>Показывать диалог с индикатором прогресса, но не показывать имен файлов</summary>
        FOF_SIMPLEPROGRESS = 0x100,
        /// <summary>Не подтверждает создание нового каталога, если операция требует, чтобы он был создан</summary>
        FOF_NOCONFIRMMKDIR = 0x200,
        /// <summary>Don't put up error UI</summary>
        FOF_NOERRORUI = 0x400,
        /// <summary>Dont copy NT file Security Attributes</summary>
        FOF_NOCOPYSECURITYATTRIBS = 0x800,
        /// <summary>Don't recurse into directories.</summary>
        FOF_NORECURSION = 0x1000,
        /// <summary>Don't operate on connected elements.</summary>
        FOF_NO_CONNECTED_ELEMENTS = 0x2000,
        /// <summary>During delete operation, warn if nuking instead of recycling (partially overrides FOF_NOCONFIRMATION)</summary>
        FOF_WANTNUKEWARNING = 0x4000,
        /// <summary>Treat reparse points as objects, not containers</summary>
        FOF_NORECURSEREPARSE = 0x8000
    }

    [Flags]
    [UsedIn(typeof(Shell32), Aditional = "SHGetFileInfo(...uFlags)")]
    public enum SHGFI
    {
        /// <summary>get icon</summary>
        Icon = 0x000000100,
        /// <summary>get display name</summary>
        DisplayName = 0x000000200,
        /// <summary>get type name</summary>
        TypeName = 0x000000400,
        /// <summary>get attributes</summary>
        Attributes = 0x000000800,
        /// <summary>get icon location</summary>
        IconLocation = 0x000001000,
        /// <summary>return exe type</summary>
        ExeType = 0x000002000,
        /// <summary>get system icon index</summary>
        SysIconIndex = 0x000004000,
        /// <summary>put a link overlay on icon</summary>
        LinkOverlay = 0x000008000,
        /// <summary>show icon in selected state</summary>
        Selected = 0x000010000,
        /// <summary>get only specified attributes</summary>
        Attr_Specified = 0x000020000,
        /// <summary>get large icon</summary>
        LargeIcon = 0x000000000,
        /// <summary>get small icon</summary>
        SmallIcon = 0x000000001,
        /// <summary>get open icon</summary>
        OpenIcon = 0x000000002,
        /// <summary>get shell size icon</summary>
        ShellIconSize = 0x000000004,
        /// <summary>pszPath is a pidl</summary>
        PIDL = 0x000000008,
        /// <summary>use passed dwFileAttribute</summary>
        UseFileAttributes = 0x000000010,
        /// <summary>apply the appropriate overlays</summary>
        AddOverlays = 0x000000020,
        /// <summary>Get the index of the overlay in the upper 8 bits of the iIcon</summary>
        OverlayIndex = 0x000000040,
    }

    //[Flags]
    //public enum SHGFI : uint
    //{
    //    SHGFI_ICON = 0x000000100,     // get icon
    //    SHGFI_DISPLAYNAME = 0x000000200,     // get display name
    //    SHGFI_TYPENAME = 0x000000400,     // get type name
    //    SHGFI_ATTRIBUTES = 0x000000800,     // get attributes
    //    SHGFI_ICONLOCATION = 0x000001000,     // get icon location
    //    SHGFI_EXETYPE = 0x000002000,     // return exe type
    //    SHGFI_SYSICONINDEX = 0x000004000,     // get system icon index
    //    SHGFI_LINKOVERLAY = 0x000008000,     // put a link overlay on icon
    //    SHGFI_SELECTED = 0x000010000,     // show icon in selected state
    //    SHGFI_ATTR_SPECIFIED = 0x000020000,     // get only specified attributes
    //    SHGFI_LARGEICON = 0x000000000,     // get large icon
    //    SHGFI_SMALLICON = 0x000000001,     // get small icon
    //    SHGFI_OPENICON = 0x000000002,     // get open icon
    //    SHGFI_SHELLICONSIZE = 0x000000004,     // get shell size icon
    //    SHGFI_PIDL = 0x000000008,     // pszPath is a pidl
    //    SHGFI_USEFILEATTRIBUTES = 0x000000010,     // use passed dwFileAttribute
    //    SHGFI_ADDOVERLAYS = 0x000000020,     // apply the appropriate overlays
    //    SHGFI_OVERLAYINDEX = 0x000000040,     // Get the index of the overlay
    //    // in the upper 8 bits of the 
    //}

    public enum SHGetFolderLocationReturnValues : uint
    {
        /// <summary>Success</summary>
        S_OK = 0x00000000,
        /// <summary>The CSIDL in nFolder is valid but the folder does not exist</summary>
        S_FALSE = 0x00000001,
        /// <summary>The CSIDL in nFolder is not valid</summary>
        E_INVALIDARG = 0x80070057
    }

    public enum CSIDL
    {
        /// <summary>Desktop</summary>
        CSIDL_DESKTOP = 0x0000,
        /// <summary>Internet Explorer (icon on desktop)</summary>
        CSIDL_INTERNET = 0x0001,
        /// <summary>Start Menu\Programs</summary>
        CSIDL_PROGRAMS = 0x0002,
        /// <summary>My Computer\Control Panel</summary>
        CSIDL_CONTROLS = 0x0003,
        /// <summary>My Computer\Printers</summary>
        CSIDL_PRINTERS = 0x0004,
        /// <summary>My Documents</summary>
        CSIDL_PERSONAL = 0x0005,
        /// <summary>user name\Favorites</summary>
        CSIDL_FAVORITES = 0x0006,
        /// <summary>Start Menu\Programs\Startup</summary>
        CSIDL_STARTUP = 0x0007,
        /// <summary>user name\Recent</summary>
        CSIDL_RECENT = 0x0008,
        /// <summary>user name\SendTo</summary>
        CSIDL_SENDTO = 0x0009,
        /// <summary>desktop\Recycle Bin</summary>
        CSIDL_BITBUCKET = 0x000a,
        /// <summary>user name\Start Menu</summary>
        CSIDL_STARTMENU = 0x000b,
        /// <summary>logical "My Documents" desktop icon</summary>
        CSIDL_MYDOCUMENTS = 0x000c,
        /// <summary>"My Music" folder</summary>
        CSIDL_MYMUSIC = 0x000d,
        /// <summary>"My Videos" folder</summary>
        CSIDL_MYVIDEO = 0x000e,
        /// <summary>user name\Desktop</summary>
        CSIDL_DESKTOPDIRECTORY = 0x0010,
        /// <summary>My Computer</summary>
        CSIDL_DRIVES = 0x0011,
        /// <summary>Network Neighborhood (My Network Places)</summary>
        CSIDL_NETWORK = 0x0012,
        /// <summary>user name>nethood</summary>
        CSIDL_NETHOOD = 0x0013,
        /// <summary>windows\fonts</summary>
        CSIDL_FONTS = 0x0014,
        CSIDL_TEMPLATES = 0x0015,
        /// <summary>All Users\Start Menu</summary>
        CSIDL_COMMON_STARTMENU = 0x0016,
        /// <summary>All Users\Start Menu\Programs</summary>
        CSIDL_COMMON_PROGRAMS = 0X0017,
        /// <summary>All Users\Startup</summary>
        CSIDL_COMMON_STARTUP = 0x0018,
        /// <summary>All Users\Desktop</summary>
        CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019,
        /// <summary>user name\Application Data</summary>
        CSIDL_APPDATA = 0x001a,
        /// <summary>user name\PrintHood</summary>
        CSIDL_PRINTHOOD = 0x001b,
        /// <summary>user name\Local Settings\Applicaiton Data (non roaming)</summary>
        CSIDL_LOCAL_APPDATA = 0x001c,
        /// <summary>non localized startup</summary>
        CSIDL_ALTSTARTUP = 0x001d,
        /// <summary>non localized common startup</summary>
        CSIDL_COMMON_ALTSTARTUP = 0x001e,
        CSIDL_COMMON_FAVORITES = 0x001f,
        CSIDL_INTERNET_CACHE = 0x0020,
        CSIDL_COOKIES = 0x0021,
        CSIDL_HISTORY = 0x0022,
        /// <summary>All Users\Application Data</summary>
        CSIDL_COMMON_APPDATA = 0x0023,
        /// <summary>GetWindowsDirectory()</summary>
        CSIDL_WINDOWS = 0x0024,
        /// <summary>GetSystemDirectory()</summary>
        CSIDL_SYSTEM = 0x0025,
        /// <summary>C:\Program Files</summary>
        CSIDL_PROGRAM_FILES = 0x0026,
        /// <summary>C:\Program Files\My Pictures</summary>
        CSIDL_MYPICTURES = 0x0027,
        /// <summary>USERPROFILE</summary>
        CSIDL_PROFILE = 0x0028,
        /// <summary>x86 system directory on RISC</summary>
        CSIDL_SYSTEMX86 = 0x0029,
        /// <summary>x86 C:\Program Files on RISC</summary>
        CSIDL_PROGRAM_FILESX86 = 0x002a,
        /// <summary>C:\Program Files\Common</summary>
        CSIDL_PROGRAM_FILES_COMMON = 0x002b,
        /// <summary>x86 Program Files\Common on RISC</summary>
        CSIDL_PROGRAM_FILES_COMMONX86 = 0x002c,
        /// <summary>All Users\Templates</summary>
        CSIDL_COMMON_TEMPLATES = 0x002d,
        /// <summary>All Users\Documents</summary>
        CSIDL_COMMON_DOCUMENTS = 0x002e,
        /// <summary>All Users\Start Menu\Programs\Administrative Tools</summary>
        CSIDL_COMMON_ADMINTOOLS = 0x002f,
        /// <summary>user name\Start Menu\Programs\Administrative Tools</summary>
        CSIDL_ADMINTOOLS = 0x0030,
        /// <summary>Network and Dial-up Connections</summary>
        CSIDL_CONNECTIONS = 0x0031,
        /// <summary>All Users\My Music</summary>
        CSIDL_COMMON_MUSIC = 0x0035,
        /// <summary>All Users\My Pictures</summary>
        CSIDL_COMMON_PICTURES = 0x0036,
        /// <summary>All Users\My Video</summary>
        CSIDL_COMMON_VIDEO = 0x0037,
        /// <summary>Resource Direcotry</summary>
        CSIDL_RESOURCES = 0x0038,
        /// <summary>Localized Resource Direcotry</summary>
        CSIDL_RESOURCES_LOCALIZED = 0x0039,
        /// <summary>Links to All Users OEM specific apps</summary>
        CSIDL_COMMON_OEM_LINKS = 0x003a,
        /// <summary>USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning</summary>
        CSIDL_CDBURN_AREA = 0x003b,
        /// <summary>Computers Near Me (computered from Workgroup membership)</summary>
        CSIDL_COMPUTERSNEARME = 0x003d,
        /// <summary>combine with CSIDL_ value to force folder creation in SHGetFolderPath()</summary>
        CSIDL_FLAG_CREATE = 0x8000,
        /// <summary>combine with CSIDL_ value to return an unverified folder path</summary>
        CSIDL_FLAG_DONT_VERIFY = 0x4000,
        /// <summary>combine with CSIDL_ value to insure non-alias versions of the pidl</summary>
        CSIDL_FLAG_NO_ALIAS = 0x1000,
        /// <summary>combine with CSIDL_ value to indicate per-user init (eg. upgrade)</summary>
        CSIDL_FLAG_PER_USER_INIT = 0x0800,
        /// <summary>mask for all possible </summary>
        CSIDL_FLAG_MASK = 0xFF00,
    }

    public enum ShowCommands
    {
        SW_HIDE = 0,
        SW_SHOWNORMAL = 1,
        SW_NORMAL = 1,
        SW_SHOWMINIMIZED = 2,
        SW_SHOWMAXIMIZED = 3,
        SW_MAXIMIZE = 3,
        SW_SHOWNOACTIVATE = 4,
        SW_SHOW = 5,
        SW_MINIMIZE = 6,
        SW_SHOWMINNOACTIVE = 7,
        SW_SHOWNA = 8,
        SW_RESTORE = 9,
        SW_SHOWDEFAULT = 10,
        SW_FORCEMINIMIZE = 11,
        SW_MAX = 11
    }
}
// ReSharper restore FieldCanBeMadeReadOnly.Global
